// api后端框架
const express = require('express');
// 数据库
const mysql = require('mysql');
// 请求体格式
const bodyParser = require('body-parser');
const cors = require('cors');
// token设置
const jwt = require('jsonwebtoken');

// 数据库链接配置
const connectionConfig = {
    host: 'localhost',
    user: 'root',
    password: '123456',
    database: 'demo'
}

// 链接数据库并把实例赋给一个变量
const pool = mysql.createConnection(connectionConfig);

// 初始化Express应用
const app = express();
app.use(bodyParser.urlencoded({ extended: false, limit: '500mb' }));//用于解析URL-encoded格式
app.use(bodyParser.json({ limit: '500mb' })); // 用于解析JSON格式的请求体
app.use(cors())



// 定义API路由以获取表中的所有数据

// 登录验证
app.post('/api/login', (req, res) => {
    // 从请求对象的query属性中获取查询参数
    const { id, psd } = req.body;
    // 解构出来前端传的参数
    console.log(id, psd);

    if (id != "" && id != undefined && psd != "" && psd != undefined) {
        // 使用连接池执行SQL查询
        pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rows) => {
            if (err) {
                // 查询错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }
            console.log("132", rows.length);
            if (rows.length <= 0) {
                console.log(1);
                return res.status(500).json({ error: "账户数据不存在" });
            }
            // 查询成功后判断，返回HTTP状态码并发送结果
            if (psd + "" == rows[0].password) {
                // 登录成功后生成token
                const payload = { userId: rows[0].id }; // 可以根据需求定义payload内容
                const secret = 'csjwt_secret'; // 定义你的JWT密钥
                const token = jwt.sign(payload, secret, { expiresIn: '1h' }); // 有效期为1小时
                // 在登录成功后记录登录日志到logindata表
                const loginTime = new Date(); // 获取当前时间
                const loginInfo = {
                    userId: rows[0].id,
                    loginTime: loginTime,
                    name: rows[0].name
                };
                const qx = rows[0].qx
                console.log(loginInfo.loginTime);
                // 插入登录日志数据
                pool.query(`INSERT INTO logindata (userId, loginTime, name) VALUES (?, ?,?)`, [loginInfo.userId, loginInfo.loginTime, loginInfo.name], (errLog) => {
                    if (errLog) {
                        console.error('Error while inserting login data:', errLog);
                    }
                });

                res.status(200).json({ token, qx });
            } else {
                res.status(400).json("密码错误!");
            }
        });
    } else {
        res.status(400).json("参数错误!");
    }
})
// 用户注册
app.post('/api/adduser1', (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { name, age, psd, info, qx, xing } = req.body;
    // 插入新用户
    console.log(name);
    pool.query(`INSERT INTO userdata (name, age,password,info,qx,xing) VALUES (?,?,?,?,?,?)`,
        [name, age, psd, info, qx, xing], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            pool.query(`SELECT LAST_INSERT_ID() AS id`, (err, rows) => {
                const userId = rows[0].id;

                // 查询成功后判断，返回HTTP状态码并发送结果
                res.status(200).json({ msg: "添加成功", userId });
            })

        });

})



// 这是与生成Token时使用的密钥，务必保持一致
const secret = 'csjwt_secret';
// 创建一个中间件用于验证JWT Token
const authenticate = (req, res, next) => {
    // 从请求头中获取Authorization字段
    const authHeader = req.headers.token;
    console.log(req.headers);
    // 如果存在Authorization字段，则尝试解析Token
    if (authHeader) {
        // Authorization字段通常由'Bearer '加上token组成，所以这里分割后取第二项
        const token = authHeader;

        try {
            // 使用密钥解码Token，得到其中包含的用户信息
            const decoded = jwt.verify(token, secret);
            // console.log("decoded", decoded);
            // 将解码后的用户信息挂载到request对象上，方便后续路由逻辑使用
            req.user = decoded;
            // 解码成功，调用next()方法将控制权交给下一个中间件或路由处理器
            next();
        } catch (err) {
            // 验证失败，返回500 Unauthorized状态码及错误信息
            return res.status(401).json({ error: 'token失效' });
        }
    } else {
        // 如果请求头中没有Authorization字段，则直接返回401 Unauthorized状态码及错误信息
        return res.status(401).json({ error: 'token不存在' });
    }
};



// 查询全用户信息（带分页）
app.get('/api/cha', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    const { pageNumber, size } = req.query;
    // 解构出来前端传的参数
    if (pageNumber && size) {
        // 转换pageNumber为数字，并调整索引从0开始计数
        const page = Number(pageNumber) - 1;
        const limit = Number(size);
        // 计算偏移量
        const offset = page * limit;
        // 使用连接池执行SQL查询
        pool.query(`SELECT * FROM userdata LIMIT ? OFFSET ?`, [limit, offset], (err, rows) => {
            if (err) {
                // 查询错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }
            if (rows) {
                pool.query('SELECT COUNT(*) AS total FROM userdata', (err, rowss) => {
                    if (err) return reject(err);
                    return res.status(200).json({ data: rows, conts: rowss[0].total });
                });
            } else {
                return res.status(500).json("数据不存在");
            }
            // 查询成功后判断，返回HTTP状态码并发送结果

        });
    } else {
        // 使用连接池执行SQL查询
        pool.query(`SELECT * FROM userdata`, (err, rows) => {
            if (err) {
                // 查询错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }
            console.log(rows);
            // 查询成功后判断，返回HTTP状态码并发送结果

            return res.status(200).json(rows);

        });
    }
})

// 登录后个人信息
app.get('/api/chause', authenticate, (req, res) => {
    // 解密后的token所携带的id
    console.log(req.user.userId);
    let id = req.user.userId
    if (id != "" && id != undefined) {
        // 使用连接池执行SQL查询
        pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rows) => {
            if (err) {
                // 查询错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }
            console.log(rows);
            // 查询成功后判断，返回HTTP状态码并发送结果

            res.status(200).json(rows);

        });
    } else {
        res.status(400).json("参数错误!");
    }
})
// 创建投票
app.post('/api/chuangdata', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    const { id, title, jie, xuan, timevalue } = req.body;
    const [runtime, stoptime] = timevalue;
    let rtime = new Date(runtime)
    let stime = new Date(stoptime)
    // 解构出来前端传的参数
    console.log(xuan);
    var itemid;
    if (id && title) {
        pool.query('START TRANSACTION', (err) => {
            if (err) {
                return res.status(500).json({ error: "事务开始出错" });
            }
            // 插入投票主题
            const insertItemResult = pool.query(`INSERT INTO itemdata (itemtitle, id,txt,runtime,stoptime) VALUES (?, ?,?,?,?)`, [title, id, jie, rtime, stime], (err, ye) => {
                if (err) {
                    return console.log(err);
                }
                pool.query(`SELECT LAST_INSERT_ID() AS itemid`, (err, row) => {
                    if (err) {
                        return console.log(err);
                    }
                    console.log("asdasdas", row);
                    itemid = row[0].itemid

                    if (typeof xuan === 'object' && xuan !== null && Object.keys(xuan).length > 0) {
                        for (let [key, value] of Object.entries(xuan)) {
                            pool.query(
                                `INSERT INTO formdata (itemid, txt,img) VALUES (?, ?,?)`,
                                [itemid, key, value]
                            );
                        }
                    } else {
                        return res.status(400).json({ error: "选项数据格式错误" });
                    }
                });
            });
        });
        // 提交事务
        pool.query('COMMIT', (err) => {
            return res.status(200).json({ msg: "创建成功" });
        });
    } else {
        return res.status(400).json("参数错误!");
    }
})
// 修改投票基本信息
app.post('/api/upitem', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);
    const { itemid, itemtitle, jie, timevalue } = req.body;
    let rtime = new Date(timevalue[0])
    let stime = new Date(timevalue[1])
    console.log(itemid);
    // 使用连接池执行SQL查询 当前操作者是否是管理员
    pool.query(`SELECT * FROM userdata WHERE id = ?`, [req.user.userId], (err, rows) => {
        if (err) {
            // 查询错误，返回HTTP状态码500并发送错误信息
            return res.status(500).json({ error: err.message });
        }
        if (rows[0].qx == 'admin') {
            // 修改
            pool.query(`UPDATE  itemdata SET itemtitle=?,txt=?,runtime=?,stoptime=? WHERE itemid=? `, [itemtitle, jie, rtime, stime, itemid], (errLog) => {
                if (errLog) {
                    return res.status(500).json({ error: errLog.message });
                }
                // 查询成功后判断，返回HTTP状态码并发送结果
                // 修改用户成功
                res.status(200).json({ message: "修改成功" });
            });
        } else {
            // 当前操作者不是管理员，无权删除用户
            res.status(200).json({ msg: "无权修改投票，请联系管理员" });
        }
    });

})

// 查询投票列表and创建记录
app.get('/api/itemdata', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    const { id, pageNumber, size } = req.query;
    // 解构出来前端传的参数
    console.log(id);
    if (pageNumber && size) {
        // 转换pageNumber为数字，并调整索引从0开始计数
        const page = Number(pageNumber) - 1;
        const limit = Number(size);
        // 计算偏移量
        const offset = page * limit;

        if (id != "" && id != undefined) {
            // 使用连接池执行SQL查询
            pool.query(`SELECT * FROM itemdata WHERE id = ? LIMIT ? OFFSET ?`, [id, limit, offset], (err, rows) => {
                if (err) {
                    // 查询错误，返回HTTP状态码500并发送错误信息
                    return res.status(500).json({ error: err.message });
                }
                if (rows) {
                    pool.query('SELECT COUNT(*) AS total FROM itemdata WHERE id = ?', [id], (err, rowss) => {
                        if (err) return reject(err);
                        console.log(rows);
                        // 查询成功后判断，返回HTTP状态码并发送结果
                        return res.status(200).json({ data: rows, conts: rowss[0].total });
                    });
                }

            });
        } else {
            pool.query(`SELECT * FROM itemdata LIMIT ? OFFSET ?`, [limit, offset], (err, rows) => {
                if (err) {
                    // 查询错误，返回HTTP状态码500并发送错误信息
                    return res.status(500).json({ error: err.message });
                }
                if (rows) {
                    pool.query('SELECT COUNT(*) AS total FROM itemdata', (err, rowss) => {
                        if (err) return reject(err);
                        console.log(rows);
                        // 查询成功后判断，返回HTTP状态码并发送结果
                        return res.status(200).json({ data: rows, conts: rowss[0].total });
                    });
                }
            });
        }
    }
})









// 删除投票
app.post('/api/delitem', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);
    const { itemid } = req.body;
    console.log(itemid);
    // 使用连接池执行SQL查询 当前操作者是否是管理员
    pool.query(`SELECT * FROM userdata WHERE id = ?`, [req.user.userId], (err, rows) => {
        if (err) {
            // 查询错误，返回HTTP状态码500并发送错误信息
            return res.status(500).json({ error: err.message });
        }
        if (rows[0].qx == 'admin') {
            // 删除用户
            pool.query(`DELETE FROM itemdata WHERE itemid = ?`, [itemid], (errLog) => {
                if (errLog) {
                    return res.status(500).json({ error: errLog.message });
                }
                // 查询成功后判断，返回HTTP状态码并发送结果
                // 删除用户成功
                res.status(200).json("删除成功");
            });
        } else {
            // 当前操作者不是管理员，无权删除用户
            res.status(403).json("无权删除投票，请联系管理员");
        }
    });

})










// 查看个人投票列表
app.get('/api/canitemdata', authenticate, (req, res) => {
    const { id, pageNumber, size } = req.query;
    console.log("aaaaaaaaaaaaa", id);

    // 将ids字符串数组转换为逗号分隔的字符串，以便在SQL查询中使用
    if (pageNumber && size) {
        // 转换pageNumber为数字，并调整索引从0开始计数
        const page = Number(pageNumber) - 1;
        const limit = Number(size);
        // 计算偏移量
        const offset = page * limit;
        pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rows) => {
            if (err) {
                // 查询错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }


            if (rows.length > 0 && rows[0].can) {
                const canarr = JSON.parse(rows[0].can)
                console.log(canarr);
                pool.query(`SELECT * FROM itemdata WHERE itemid IN (?)`, [canarr], (err, rowss) => {
                    if (err) {
                        return res.status(500).json({ error: err.message });
                    }
                    console.log(rowss);
                    // 查询成功，返回数据
                    res.status(200).json({ data: rowss });
                });
            } else {
                return res.status(200).json({ msg: "没有参与记录" });
            }
        });

    }
});



// 获取投票选项
app.get('/api/getuseitem', (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { itemid } = req.query;

    pool.query(`SELECT * FROM formdata WHERE itemid = ?`, [itemid], (err, rows) => {
        if (err) {
            return res.status(500).json({ error: err.message });
        }
        res.status(200).json({ data: rows });

    })

})







// 参与投票
app.post('/api/useitem', (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { itemid, id, usetxt } = req.body;
    // 插入
    pool.query(`INSERT INTO usedata (itemid,id,usetxt) VALUES (?,?,?)`,
        [itemid, id, usetxt], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            pool.query(`SELECT * FROM formdata WHERE itemid = ? AND txt = ?`, [itemid, usetxt], (err, rows) => {
                if (err) {
                    return res.status(500).json({ error: err.message });
                }
                let num = rows[0].chang++
                num++
                console.log(num);
                pool.query(`UPDATE formdata SET chang = ? WHERE itemid = ? AND txt = ?`, [num, itemid, usetxt], (error, rowss) => {
                    if (error) {
                        return res.status(500).json({ error: error.message });
                    }
                    pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rowsa) => {
                        if (err) {
                            // 查询错误，返回HTTP状态码500并发送错误信息
                            return res.status(500).json({ error: err.message });
                        }
                        let arr = rowsa[0].can ? JSON.parse(rowsa[0].can) : []
                        arr.push(Number(itemid))
                        console.log(arr);
                        arr = JSON.stringify(arr)

                        pool.query(`UPDATE userdata SET can = ? WHERE id = ?`, [arr, id], (err, rowsss) => {
                            res.status(200).json({ msg: "投票成功" });
                        })


                    });
                })
            })
        });
})




// 查询登录记录
app.get('/api/longinfo', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);

    // 使用连接池执行SQL查询
    pool.query(`SELECT * FROM logindata`, (err, rows) => {
        if (err) {
            // 查询错误，返回HTTP状态码?00并发送错误信息
            return res.status(500).json({ error: err.message });
        }
        console.log(rows);
        // 查询成功后判断，返回HTTP状态码并发送结果

        res.status(200).json(rows);

    });

})

// 创建用户
app.post('/api/adduser', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);
    const { name, age, psd, info, qx } = req.body;
    // 使用连接池执行SQL查询 当前操作者是否是管理员
    pool.query(`SELECT * FROM userdata WHERE id = ?`, [req.user.userId], (err, rows) => {
        if (err) {
            // 查询错误，返回HTTP状态码500并发送错误信息
            return res.status(500).json({ error: err.message });
        }
        if (rows[0].qx == 'admin') {
            // 插入新用户
            pool.query(`INSERT INTO userdata (name, age,password,info,qx) VALUES (?,?,?,?,?)`,
                [name, age, psd, info, qx], (errLog) => {
                    if (errLog) {
                        return res.status(500).json({ error: errLog.message });
                    }
                    // 查询成功后判断，返回HTTP状态码并发送结果
                    res.status(200).json("添加成功");
                });
        }
    });

})
// 删除用户
app.post('/api/deluser', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);
    const { id } = req.body;
    // 使用连接池执行SQL查询 当前操作者是否是管理员
    pool.query(`SELECT * FROM userdata WHERE id = ?`, [req.user.userId], (err, rows) => {
        if (err) {
            // 查询错误，返回HTTP状态码500并发送错误信息
            return res.status(500).json({ error: err.message });
        }
        if (rows[0].qx == 'admin') {
            // 删除用户
            pool.query(`DELETE FROM userdata WHERE id = ?`, [id], (errLog) => {
                if (errLog) {
                    return res.status(500).json({ error: errLog.message });
                }
                // 查询成功后判断，返回HTTP状态码并发送结果
                // 删除用户成功
                res.status(200).json("删除成功");
            });
        } else {
            // 当前操作者不是管理员，无权删除用户
            res.status(403).json("无权删除用户");
        }
    });

})
// 修改个人信息
app.post('/api/updateuser', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    console.log(req.user);
    const { name, age, psd, id, xing, newpsd, qx, zw, uu } = req.body;
    console.log(uu);
    console.log(newpsd);
    if (newpsd != "null" && uu == undefined) {
        // 修改个人密码
        console.log(11111);
        // 使用连接池执行SQL查询 当前操作者密码验证
        pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rows) => {
            if (rows[0].password == psd) {
                pool.query(`UPDATE userdata SET password = ? WHERE id = ?`, [newpsd, id], (err, rows2) => {
                    if (err) {
                        // 更新错误，返回HTTP状态码500并发送错误信息
                        return res.status(500).json({ error: err.message });
                    }
                    // 更新成功，返回受影响行数
                    if (rows2.affectedRows > 0) {
                        return res.status(200).json({ message: '密码更新成功已更新(即将跳转登录页面重新登录)' });
                    } else {
                        return res.status(404).json({ error: '未找到相应用户记录' });
                    }
                });
            } else {
                return res.status(200).json({ error: '旧密码错误' });
            }
        });
    } else if (uu) {
        // 管理员修改全用户
        console.log(111111111);
        pool.query(`UPDATE userdata SET name = ?, age = ?,xing = ?,password = ?,qx = ?,info = ? WHERE id = ?`, [name, age, xing, newpsd, qx, zw, id], (err, rows2) => {
            if (err) {
                // 更新错误，返回HTTP状态码500并发送错误信息
                return res.status(500).json({ error: err.message });
            }
            console.log(rows2);
            // 更新成功，返回受影响行数
            if (rows2.affectedRows > 0) {
                return res.status(200).json({ message: '用户信息已更新' });
            } else {
                return res.status(404).json({ error: '未找到相应用户记录' });
            }
        });


    } else {
        // 修改个人信息
        console.log(111111111222222);
        // 使用连接池执行SQL查询 当前操作者密码验证
        pool.query(`SELECT * FROM userdata WHERE id = ?`, [id], (err, rows) => {
            if (rows[0].password == psd) {
                pool.query(`UPDATE userdata SET name = ?, age = ?,xing = ? WHERE id = ?`, [name, age, xing, id], (err, rows2) => {
                    if (err) {
                        // 更新错误，返回HTTP状态码500并发送错误信息
                        return res.status(500).json({ error: err.message });
                    }
                    // 更新成功，返回受影响行数
                    if (rows2.affectedRows > 0) {
                        return res.status(200).json({ message: '用户信息已更新' });
                    } else {
                        return res.status(404).json({ error: '未找到相应用户记录' });
                    }
                });
            } else {
                return res.status(200).json({ error: '密码错误' });
            }
        });
    }
})
// 创建反馈
app.post('/api/addfk', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { txt, userid } = req.body;

    // 插入新数据
    pool.query(`INSERT INTO fk (txt,userid) VALUES (?,?)`,
        [txt, userid], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            // 查询成功后判断，返回HTTP状态码并发送结果
            res.status(200).json({ msg: "反馈成功" });
        });

})
// 评论反馈
app.post('/api/addfkhf', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { fkid, txt, userid } = req.body;

    // 插入新数据
    pool.query(`INSERT INTO fkhf (fkid,txt,useid) VALUES (?,?,?)`,
        [fkid, txt, userid], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            // 查询成功后判断，返回HTTP状态码并发送结果
            res.status(200).json({ msg: "回复成功" });
        });

})
// 渲染反馈
app.get('/api/fkdata', authenticate, (req, res) => {

    // 查询所有反馈
    pool.query(`SELECT * FROM fk `, (errLog, row) => {
        if (errLog) {
            return res.status(500).json({ error: errLog.message });
        }
        // 查询成功后判断，返回HTTP状态码并发送结果
        res.status(200).json(row);
    });

})
// 渲染反馈评论
app.get('/api/fkhfdata', authenticate, (req, res) => {

    // 查询所有
    pool.query(`SELECT * FROM fkhf `, (errLog, row) => {
        if (errLog) {
            return res.status(500).json({ error: errLog.message });
        }
        // 查询成功后判断，返回HTTP状态码并发送结果
        res.status(200).json(row);
    });

})
// 发布公告
app.post('/api/addgong', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { txt, k } = req.body;
    const thisTime = new Date();
    // 插入新数据
    pool.query(`INSERT INTO gao (txt,tiem,k) VALUES (?,?,?)`,
        [txt, thisTime, k], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            // 查询成功后判断，返回HTTP状态码并发送结果
            res.status(200).json({ msg: "发布成功" });
        });

})
// 获取公告
app.get('/api/gaodata', authenticate, (req, res) => {

    // 查询所有
    pool.query(`SELECT * FROM gao `, (errLog, row) => {
        if (errLog) {
            return res.status(500).json({ error: errLog.message });
        }
        // 查询成功后判断，返回HTTP状态码并发送结果
        res.status(200).json(row);
    });

})
// 修改公告状态
app.post('/api/upgong', authenticate, (req, res) => {
    // 从请求对象的query属性中获取查询参数
    // 解构出来前端传的参数
    const { k, gaoid } = req.body;
    // 修改数据
    pool.query(`UPDATE gao SET k=? WHERE gaoid = ? `,
        [k, gaoid], (errLog) => {
            if (errLog) {
                return res.status(500).json({ error: errLog.message });
            }
            // 查询成功后判断，返回HTTP状态码并发送结果
            res.status(200).json({ msg: "更改成功" });
        });

})
// 启动服务器监听指定端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`服务已经开启。后台接口地址： http://localhost,端口： ${PORT}`));